import { observe } from './observer/index.js'

export function initState(vm) {
  // 根据vm中不同的选项做不同的初始化
  const opts = vm.$options
  if (opts.data) {
    initData(vm)
  }
}

function proxy(vm, source, key) {
  // 劫持的是vm中，但是没有劫持方法，因为劫持的属性是外面传进来的
  Object.defineProperty(vm, key, {
    get() {
      // 代理到vm._data中 = data
      return vm[source][key]
    },
    set(newVal) {
      vm[source][key] = newVal
    }
  })
}

// 初始化data数据
function initData(vm) {
  let data = vm.$options.data
  // 如果是函数调用函数取到返回值，对返回值的数据进行劫持,并将data中的this指向vue实例
  // 如果不是函数直接拿到数据
  data = vm._data = typeof data === 'function' ? data.call(vm) : data
  for (let key in vm._data) {
    proxy(vm, '_data', key)
  }
  // 对data数据进行劫持侦测
  observe(data)
}
